package com.hup.minicontroller.server.screenImageService;

import android.graphics.Point;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.util.Log;
import android.view.Surface;

import java.io.IOException;

/**
 * 使用{@link MediaCodec}处理录屏数据
 * https://www.jianshu.com/p/8b313692ac85
 * 没实现功能,仅记录有这种方法
 */
public class MediaCodecProcessor implements IScreenDataProcessor {
    private static final String TAG = MediaCodecProcessor.class.getSimpleName();
    private static final long READ_TIMEOUT = 5000;

    public boolean debug = true;
    private MediaCodec codec;
    private boolean running;
    private BufferInfo bufferInfo;

    public MediaCodecProcessor(Point screenSize) {
        if (debug) throw new IllegalArgumentException("未实现!");
        String mineType = MediaFormat.MIMETYPE_VIDEO_AVC;
        MediaFormat format = MediaFormat.createVideoFormat(mineType, screenSize.x, screenSize.y);
        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
        //下面参数没深究
//        format.setInteger(MediaFormat.KEY_BIT_RATE, ???);
//        format.setInteger(MediaFormat.KEY_FRAME_RATE, ???);//??
//        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, ???);//??

        try {
            codec = MediaCodec.createEncoderByType(mineType);
            codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
            codec.start();
            bufferInfo = new BufferInfo();
            new Thread() {
                @Override
                public void run() {
                    running = true;
                    while (running) handleData();
                }
            }.start();
        } catch (IOException e) {
            codec = null;
            Log.e(TAG, "MediaCodecProcessor: ", e);
        }
    }

    @Override
    public Surface getSurface() {
        if (codec == null) {
            return null;
        }
        return codec.createInputSurface();
    }

    private void handleData() {
        int index = codec.dequeueOutputBuffer(bufferInfo, READ_TIMEOUT);
        if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            resetOutputFormat();//???
        } else if (index == MediaCodec.INFO_TRY_AGAIN_LATER) {
            try {
                // wait 10ms
                Thread.sleep(10);
            } catch (InterruptedException e) {
                Log.e(TAG, "handleData: ", e);
                Thread.currentThread().interrupt();
                running = false;
            }
        } else if (index >= 0) {
//            encodeToVideoTrack(index);//???
            codec.releaseOutputBuffer(index, false);
        }
    }

    private void resetOutputFormat() {

    }

    @Override
    public void release() {
        running = false;
        if (codec != null) {
            codec.release();
        }
    }

}
